#ifndef TCP_CLIENT_H_
#define TCP_CLIENT_H_

#include <string>

#include "netlib/base/noncopyable.h"
#include "netlib/net/call_backs.h"
#include "netlib/net/socket/connector.h"
#include "netlib/net/socket/inet_address.h"
#include "netlib/net/socket/tcp_connection.h"

namespace netlib::net {

class EventLoop;

class TcpClient : NonCopyable {
public:
	TcpClient(EventLoop* loop, const InetAddress& addr, std::string&& name = "client");
	~TcpClient();

	std::string Name() const { return kName; }
	void SetConnectionCallback(const ConnectionCallback& cb) { connection_callback_ = cb; }
	void SetMessageCallback(const MessageCallback& cb) { message_callback_ = cb; }
	void SetWriteCompleteCallback(const WriteCompleteCallback& cb) {
		write_complete_callback_ = cb;
	}

	void Connect();
	void Disconnect();
	void Stop();
	bool IsConnected() const { return connection_ && connection_->Connected(); }
	void Send(const std::string& msg) {
		if (connection_ && connection_->Connected()) {
			connection_->Send(msg);
		}
	}

	void DefaultConnectionCallback(const TcpConnectionPtr& conn);
	const InetAddress& GetTargetAddress() const { return connection_->PeerAddress(); }

private:
	void NewConnection(int sockfd);
	void RemoveConnection(const TcpConnectionPtr& conn);

	EventLoop* loop_;
	Connector connector_;
	const std::string kName;
	ConnectionCallback connection_callback_;
	MessageCallback message_callback_;
	WriteCompleteCallback write_complete_callback_;
	TcpConnectionPtr connection_;
};

} // namespace netlib::net

#endif